package com.seeTools.next.service.sys.impl;

import cn.hutool.core.text.CharSequenceUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.seeTools.next.api.entity.sys.SysRole;
import com.seeTools.next.api.entity.sys.SysRoleMenu;
import com.seeTools.next.api.entity.sys.SysUserRole;
import com.seeTools.next.common.constant.Constants;
import com.seeTools.next.common.core.PageQuery;
import com.seeTools.next.mapper.sys.SysRoleMapper;
import com.seeTools.next.service.BaseServiceImpl;
import com.seeTools.next.service.sys.ISysRoleMenuService;
import com.seeTools.next.service.sys.ISysRoleService;
import com.seeTools.next.service.sys.ISysUserRoleService;
import com.seeTools.next.util.PageQueryHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统角色 服务实现类
 * </p>
 *
 * @author FallenDust
 * @since 2023-05-10
 */
@Slf4j
@CacheConfig(cacheNames = "sysRoleCache")
@Service
public class SysRoleServiceImpl extends BaseServiceImpl<SysRoleMapper, SysRole> implements ISysRoleService {

    @Resource
    private PageQueryHelper<SysRole> pageQueryHelper;

    @Resource
    private ISysRoleMenuService sysRoleMenuService;
    @Resource
    private ISysUserRoleService sysUserRoleService;

    @Override
    public Page<SysRole> pageInfo(PageQuery<SysRole> pageQuery) {
        SysRole params = pageQuery.getParams();
        // 根据查询参数组装查询wrapper
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<SysRole> lambdaQueryWrapper = queryWrapper.lambda();
        if (CharSequenceUtil.isNotEmpty(params.getRoleName())) {
            lambdaQueryWrapper.like(SysRole::getRoleName, params.getRoleName());
        }
        // 查询
        return pageQueryHelper.pageInfo(this, pageQuery, queryWrapper);
    }


    @Override
    @CacheEvict(cacheNames = Constants.CacheKey.ROLE_LIST_TENANT_ID, key = "#entity.tenantId")
    public boolean save(SysRole entity) {
        return super.save(entity);
    }


    @Override
    @CacheEvict(cacheNames = Constants.CacheKey.ROLE_LIST_TENANT_ID, key = "#entity.tenantId")
    public boolean removeById(SysRole entity) {
        return super.removeById(entity);
    }


    @Override
    @CacheEvict(cacheNames = Constants.CacheKey.ROLE_LIST_TENANT_ID, key = "#entity.tenantId")
    public boolean updateById(SysRole entity) {
        return super.updateById(entity);
    }


    @Override
    @Cacheable(cacheNames = Constants.CacheKey.ROLE_LIST_TENANT_ID, key = "#tenantId", unless = "#result.size() == 0")
    public List<SysRole> getRoleListCache(Long tenantId) {
        log.debug("@getRoleListCache#db#tenantId={}", tenantId);
        return this.list(new LambdaQueryWrapper<SysRole>().eq(SysRole::getActive, 1));
    }

    @Override
    @Cacheable(cacheNames = Constants.CacheKey.ROLE_MENU_LIST, key = "#roleId", unless = "#result.size() == 0")
    public List<SysRoleMenu> getRoleMenuList(Long roleId) {
        return sysRoleMenuService.list(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, roleId));
    }

    @Override
    @CacheEvict(cacheNames = Constants.CacheKey.ROLE_MENU_LIST, key = "#roleId")
    public void assignMenus(Long roleId, List<Long> menuIds) {
        // 删除当前角色的菜单关联
        sysRoleMenuService.removeByRoleId(roleId);
        // 新增角色菜单关联
        List<SysRoleMenu> roleMenuList = new ArrayList<>();
        for (Long menuId : menuIds) {
            roleMenuList.add(SysRoleMenu.builder().roleId(roleId).menuId(menuId).build());
        }
        if (!roleMenuList.isEmpty()) {
            sysRoleMenuService.saveBatch(roleMenuList);
        }
    }

    @Override
    public List<SysRole> getRoleListByUserId(Long userId) {
        List<SysUserRole> userRoleList = sysUserRoleService.list(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId));
        if (userRoleList.isEmpty()) {
            return Collections.emptyList();
        }
        List<Long> roleIdList = userRoleList.stream().map(SysUserRole::getRoleId).distinct().collect(Collectors.toList());
        return this.list(new LambdaQueryWrapper<SysRole>().in(SysRole::getId, roleIdList));
    }
}
